using LiJ.Common.Core;
using System;
using System.Threading;

namespace LiJ.Http.Extention
{
	/// <summary>
	///   请求基类
	/// </summary>
	/// <typeparam name="TRestType"></typeparam>
	public class BaseRestApi<TRestType> : BaseRestApi<TRestType, AppConfig> where TRestType : class, new()
	{
		/// <summary>
		///  构造函数
		/// </summary>
		/// <param name="config"></param>
		public BaseRestApi(AppConfig config = null)
			: base(config)
		{
		}
	}
	/// <summary>
	/// 通用App接口请求基类
	/// </summary>
	/// <typeparam name="TRestType"></typeparam>
	/// <typeparam name="TConfigType"></typeparam>
	public class BaseRestApi<TRestType, TConfigType> where TRestType : class, new()where TConfigType : class, new()
	{
		private static readonly AsyncLocal<TConfigType> ContextConfig = new AsyncLocal<TConfigType>();

		private readonly TConfigType _config;

		private static object _lockObj = new object();

		private static TRestType _instance;

		/// <summary>
		///   默认配置信息，如果实例中的配置为空会使用当前配置信息
		/// </summary>
		public static TConfigType DefaultConfig
		{
			get;
			set;
		}

		/// <summary>
		/// 微信接口配置
		/// </summary>
		public TConfigType ApiConfig
		{
			get
			{
				if (this._config != null)
				{
					return this._config;
				}
				if (ContextConfig.Value != null)
				{
					return ContextConfig.Value;
				}
				if (DefaultConfig != null)
				{
					return DefaultConfig;
				}
				throw new ArgumentNullException("当前配置信息为空，请通过SetContextConfig方法设置,或者构造函数中赋值，或者也可以程序入口处给 DefaultConfig 赋值");
			}
		}

		/// <summary>
		///   接口请求实例  
		///  当 DefaultConfig 设值之后，可以直接通过当前对象调用
		/// </summary>
		public static TRestType Instance
		{
			get
			{
				if (_instance != null)
				{
					return _instance;
				}
				lock (_lockObj)
				{
					if (_instance == null)
					{
                        _instance = new TRestType();
					}
				}
				return _instance;
			}
		}

		/// <summary>
		///   当前模块名称
		///     方便日志追踪
		/// </summary>
		protected static string ModuleName
		{
			get;
			set;
		} = "default";


		/// <summary>
		///  设置上下文配置信息，当前配置在当前上下文中有效
		/// </summary>
		/// <param name="config"></param>
		public static void SetContextConfig(TConfigType config)
		{
            ContextConfig.Value = config;
		}

		/// <summary>
		/// 构造函数
		/// </summary>
		/// <param name="config"></param>
		public BaseRestApi(TConfigType config = null)
		{
            _config = config;
		}
	}
}
